#include "Thread.h"

namespace Core
{
	rtThread::rtThread(void):
    m_ThreadHandle(NULL),
	m_IsRunning(false),
	m_IsTerminating(false)
	{
	}


	rtThread::~rtThread(void)
	{
		stopThread(true);
		destroyThread();
	}

	inline std::string rtThread::getName()
	{
		return m_Name;
	}

	inline ThreadPriority rtThread::getThreadPriority()
	{
		return m_ThreadPriority;
	}

	inline void rtThread::setThreadPriority(ThreadPriority priority)
	{
		m_ThreadPriority = priority;
		int windowThreadPriority = THREAD_PRIORITY_NORMAL;
		switch(m_ThreadPriority)
		{
		case PRIORITY_MAX:
			windowThreadPriority = THREAD_PRIORITY_HIGHEST;
			break;
		case PRIORITY_HIGH:
			windowThreadPriority = THREAD_PRIORITY_ABOVE_NORMAL;
			break;
		case PRIORITY_NOMINAL:
			windowThreadPriority = THREAD_PRIORITY_NORMAL;
			break;
		case PRIORITY_LOW:
			windowThreadPriority = THREAD_PRIORITY_BELOW_NORMAL;
			break;
		case PRIORITY_MIN:
			windowThreadPriority = THREAD_PRIORITY_LOWEST;
			break;
		}

		if(m_ThreadHandle)
		{
			::SetThreadPriority(m_ThreadHandle, windowThreadPriority);
		}
	}
	bool rtThread::startThread(std::string name, ThreadPriority priority, int stackSize)
	{
		if(m_IsRunning)
		{
			return false;
		}

		m_Name = name;
		m_ThreadPriority = priority;
		m_StackSize = stackSize;
		if(m_ThreadHandle)
		{
			destroyThread();
		}
		createThread();
		m_IsRunning = true;
		return true;
	}

	void rtThread::stopThread(bool bWait)
	{
		if(m_IsRunning == false)
		{
			return;
		}

		m_IsTerminating = true;

		if (bWait == true)
		{
			waitForThread();
		}
	}

	void rtThread::createThread()
	{
		DWORD flags = STACK_SIZE_PARAM_IS_A_RESERVATION;
		DWORD threadID;
		m_ThreadHandle = ::CreateThread(NULL, m_StackSize, (LPTHREAD_START_ROUTINE)ThreadRountine, this, flags, &threadID);
		if(m_ThreadHandle)
		{
			setThreadPriority(m_ThreadPriority);
		}
	}

	void rtThread::destroyThread()
	{
		if(m_ThreadHandle == NULL)
		{
			return;
		}
		WaitForSingleObject(m_ThreadHandle, INFINITE);
		CloseHandle(m_ThreadHandle);
		m_ThreadHandle = NULL;
	}

	

	void rtThread::waitForThread()
	{
		if(m_IsRunning)
		{
			destroyThread();
		}
	}

	int rtThread::ThreadRountine(rtThread* pThread)
	{
		int ret = 0;
		ret = pThread->run();
		pThread->m_IsRunning = false;
		return ret;
	}

}

